import mitt from "mitt";
import { defineStore } from "pinia";
import { Toast } from "vant";
import { hub } from "../canvas/hub";
import { Layer } from "../canvas/System/Layer";
import { Move } from "../Entity/Move";
import { Paint } from "../Entity/Paint";
import { Pen, Eraser, PenRect } from "../Entity/Pen";
import { Tool } from "../Entity/Tool";
import { Tools } from "./Tools";

export const ToolHub = mitt<{
    usePaintFill: { x: number; y: number; layer: Layer };
}>();

type Collection = { id: string; name: string; entity: Tool };
export const useToolStore = defineStore("canvas", {
    state: () => {
        const paint = new Paint();
        ToolHub.on("usePaintFill", ({ x, y, layer }) => {
            paint.drawStart({ layer, data: { x, y } });
        });
        // index 必须和上面的 enum 一致
        const collection: Collection[] = [
            {
                id: "Pen",
                name: "钢笔",
                entity: new Pen(),
            },
            {
                id: "Eraser",
                name: "橡皮",
                entity: new Eraser(),
            },
            {
                id: "Paint",
                name: "油漆桶",
                entity: paint,
            },
            {
                id: "PenRect",
                name: "方型笔",
                entity: new PenRect(),
            },
            {
                id: "Move",
                name: "移动",
                entity: new Move(),
            },
        ];

        return {
            // 这里用 Map 是因为普通的对象在处理成 store 时 会被删减，
            // 所以使用 Map 指向原来的对象就不会被处理了
            tools: collection.map((i) => {
                const entity = new Map([["entity", i.entity]]);
                return { ...i, entity };
            }),
            selected: {
                Tool: Tools.Pen,
            },
        };
    },
    getters: {
        /** 用户正在使用的工具 */
        usingTool: (state) => {
            // index 是一致的
            return state.tools[state.selected.Tool].entity.get("entity")!;
        },
    },
    actions: {
        changeTool(index: Tools) {
            this.usingTool.closed();

            if (this.selected.Tool !== index) {
                this.selected.Tool = index;
                this.usingTool.prepare();
                hub.emit("refreshBrush");
                hub.emit("changeTool", this.usingTool);
                Toast({
                    message: `工具更换 ${this.usingTool.name}`,
                    position: "bottom",
                });
            }
        },
        changeBlend() {
            this.usingTool.blend = this.usingTool.blend ? 0 : 1;
        },
    },
});
